#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<string.h>
#include<fcntl.h>
#include<errno.h>
#include"mytbf.h"
#include<unistd.h>
typedef void (*sighandler_t)(int);
struct mytbf_st
{
	int cps;
	int burst;
	int token;
	int pos;
};

static struct mytbf_st* job[MYTBF_MAX];
static int inited=0;
static sighandler_t alrm_handlersave;


static int getpos()
{
	int i;
	for(i=0;i<MYTBF_MAX;i++)
	{
		if(job[i]==NULL)
		{

//			printf("获取位置%d\n",i);
			return i;
		}
	}
	return -1;
}
static void alrm_handler(int s)
{
	int i;
	alarm(1);
	for(i=0;i<MYTBF_MAX;i++)
	{	
		//printf("正在判断位置,%d的\n",i);
		//printf("%d\n",job[i]->cps);
		if(job[i]!=NULL)
		{
			job[i]->token+=job[i]->cps;
		//	printf("开始增加token%d\n",job[i]->token);
			if(job[i]->token>job[i]->burst)
				job[i]->token=job[i]->burst;
		
		
		//	printf("%d位置的TOKEN值是%d\n",i,job[i]->token);
		}
		//printf("%d位置的TOKEN值是%d\n",i,job[i]->token);

	}
}

static void module_unload()
{

	int i;
	signal(SIGALRM,alrm_handlersave);
	alarm(0);
	for(i=0;i<MYTBF_MAX;i++)
	{
		free(job[i]);
	}

}

static void module_load()
{
	alrm_handlersave=signal(SIGALRM,alrm_handler);
//	printf("模块载入成功\n");
	alarm(1);
	atexit(module_unload);
}


mytbf_t *mytbf_init(int cps,int burst)
{
	struct mytbf_st *me;
	int pos;
	if(!inited)
	{
	
		module_load();
		inited=1;
	}
	pos=getpos();
	if(pos<0)
		return NULL;
	me=malloc(sizeof(*me));
	if(me==NULL)
		return NULL;

	me->cps=cps;
//	printf("cps=%d ",me->cps);
	me->burst=burst;
//	printf("burst=%d",me->burst);
	me->token=0;
//	printf("token=%d",me->token);
	me->pos=pos;
//	printf("pos=%d",me->pos);
//	printf("初始化成功\n");
	job[pos]=me;
	return me;

}

int mytbf_destroy(mytbf_t*ptr)
{
	struct mytbf_st *me=ptr;
	job[me->pos]=NULL;
	free(me);
	return 0;
	


}


static int min(int a,int b)
{
	if(a<b)
		return a;
	return b;

}
int mytbf_fetchtoken(mytbf_t *ptr,int size)
{

	struct mytbf_st *me=ptr;
	int n;
//	printf("输入的SIZE%d\n",size);
	if(size<=0)
		return -EINVAL;
//	printf("当前的token%d\n",me->token);
	while(me->token<=0)
	{

//		printf("开始等待\n");
		pause();
	}
	n=min(me->token,size);
//	printf("最小%d",n);
	me->token-=n;
//	printf("获取token%d\n",n);
	return n;

}

int mytbf_returntoken(mytbf_t *ptr,int size)
{
	struct mytbf_st *me=ptr;
	if(size<=0)
		return -EINVAL;
	me->token+=size;
	if(me->token>me->burst)
		me->token=me->burst;
//	printf("返回token%d\n",size);
	return size;
}
